Add fixedsizearray trait and StaticArrays support#39
Open
Conversation
Generalize the fixed-size array construction path so that any array
type that can't be grown via push! can be handled by pre-allocating a
Memory{T} buffer, filling it via setindex!, and converting to the
target type.
New public API:
- `fixedsizearray(::Type{T})`: trait for types needing pre-allocate+fill
- `discover_dims(style, ::Type{T}, source)`: type-based dimension discovery
- `arrayfromdata(::Type{T}, mem, dims)`: convert filled buffer to target type
- `FixedArrayClosure`: setindex!-based 1D fill closure
The StaticArraysCore extension overrides these to:
- Read dimensions from type parameters (no JSON scanning)
- Convert Memory to StaticArray via Tuple (native representation)
Closes JuliaIO/JSON.jl#429
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The arrayfromdata method uses Memory in its signature, which only exists on Julia >= 1.11. Without the guard, the extension would fail to precompile on older Julia versions. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use Vector{ET} as the pre-allocated buffer on Julia < 1.11 where
Memory does not exist. Add arrayfromdata(::Type, ::Vector, ::Tuple)
methods in both the main module and the StaticArraysCore extension
so the fixed-size array path works on all supported Julia versions.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
fixedsizearraytrait to generalize the pre-allocate +setindex!array construction path (currently only used forndims > 1arrays) to any fixed-size array typeStaticArraysCorepackage extension that enablesStructUtils.makeforSVector,SMatrix,MVector, and otherStaticArraytypesMemory{T}as the flat backing buffer on Julia 1.11+, with the existing growable path as fallbackMotivation
StructUtils.makearrayassumes all 1D arrays are growable (push!intoT(undef, 0)). This fails forStaticArrayswhich are fixed-size and immutable. Thendims > 1path already uses a pre-allocate +setindex!approach — this PR generalizes that pattern.Closes JuliaIO/JSON.jl#429
New public API
fixedsizearray(::Type{T})discover_dims(style, ::Type{T}, source)arrayfromdata(::Type{T}, mem, dims)Memorybuffer to target type TFixedArrayClosuresetindex!-based 1D fill closure (vspush!-basedArrayClosure)How it works
For
fixedsizearraytypes on Julia 1.11+:discover_dimsgets dimensions (from type params for StaticArrays, source scan for regular Matrix)Memory{eltype(T)}(undef, prod(dims))allocates a flat bufferFixedArrayClosurefills via linearsetindex!; nD:MultiDimClosurefills via reshaped viewarrayfromdataconverts the filled Memory to the target typeThe StaticArraysCore extension (3 methods):
fixedsizearray(::Type{<:StaticArray}) = truediscover_dimsreads dimensions from type parameters (no source scanning)arrayfromdataconverts viaT(Tuple(mem))(StaticArrays' native representation)Test plan
Pkg.test())JSON.parse("[1,2,3]", SVector{3,Int})works🤖 Generated with Claude Code